home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 2
/
Deutsche Edition 2.iso
/
mac
/
POWERMAC
/
C64
/
SOURCE
/
Instructions68K.c
< prev
next >
Wrap
Text File
|
1994-06-06
|
22KB
|
1,546 lines
/*
Commodore 64 Emulator v0.4 Earle F. Philhower III
Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
High Speed 68K CPU by George T. Talbot
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MWERKS__
#include "Processor.h"
#include "Registers68K.h"
#include "Flags68K.h"
#include "Instructions68K.h"
#include "Stack68K.h"
#include "Modes68K.h"
#include "Memory68K.h"
/* Rather than using multiplication and division to do the BCD math, it's implemented
* with lookup tables--faster and easier to code in 68K assembly.
* These are defined in Instructions.c
*/
extern unsigned char bcd2dec[];
extern unsigned char dec2bcd[];
/* To try to improve the hit-rate on the cached processors (68030, 68040), I tried
* to make the routines shorter by having them come here to set the ZER and NEG
* flags. This incurs a 2 instruction penalty every time it's used, but hopefully
* it'll speed up the other aspects. (We'll have to test it). This shaves about
* 1K off the CPU emulation code size.
*/
void doFlagsNZ()
{
asm {
ANDI.B #0xFF-(ZER|NEG),rFLAGS
TST.B D0
BEQ @1
NegSet(D0)
RTS
@1 BSET #bZER,rFLAGS
}
}
/* Here follow the instructions. They are pretty much translated from their C
* counterparts. The same macro names are used, for consistency.
*/
void i00f()
{
asm {
PushWord(rPC)
Push(rFLAGS)
OR.B #BKC,rFLAGS
WordAt(IrqTo, rPC)
}
}
void i01f() /*{ ORA(IndirectXAddr); pc++; }*/
{
asm {
ORA(IndirectXAddr)
PC(#1)
}
}
void i05f() /*{ ORA(ZeroPageAddr); pc++; }*/
{
asm {
ORA(ZeroPageAddr)
PC(#1)
}
}
void i06f() /*{ ASL(ZeroPageAddr); pc++; }*/
{
asm {
ASL(ZeroPageAddr)
PC(#1)
}
}
void i08f()
{
asm {
Push(rFLAGS)
}
}
void i09f() /*{ a |= ImmediateByte(); FlagsNZ(a); pc++; }*/
{
asm {
ImmediateByte(D1)
OR.B D1,rA
FlagsNZ(rA)
PC(#1)
}
}
void i0af() /*{
if (a&128) flags |= CAR;
else flags &= ~CAR;
a=a<<1;
FlagsNZ(a); }*/
{
asm {
ANDI.B #0xFF-CAR,rFLAGS
BTST #7,rA
BEQ @3
ORI.B #CAR,rFLAGS
@3 LSL.B #1,rA
FlagsNZ(rA)
}
}
void i0df() /*{ ORA(AbsoluteAddr); pc+=2; }*/
{
asm {
ORA(AbsoluteAddr)
PC(#2)
}
}
void i0ef() /*{ ASL(AbsoluteAddr); pc+=2; }*/
{
asm {
ASL(AbsoluteAddr)
PC(#2)
}
}
void i10f() /*{ BCL(NEG); }*/
{
asm {
BCL(#bNEG)
}
}
void i11f() /*{ ORA(IndirectYAddr); pc++; }*/
{
asm {
ORA(IndirectYAddr)
PC(#1)
}
}
void i15f() /*{ ORA(ZeroPageXAddr); pc++; }*/
{
asm {
ORA(ZeroPageXAddr)
PC(#1)
}
}
void i16f() /*{ ASL(ZeroPageXAddr); pc++; }*/
{
asm {
ASL(ZeroPageXAddr)
PC(#1)
}
}
void i18f() /*{ CLR(CAR); }*/
{
asm {
CLR(#bCAR)
}
}
void i19f() /*{ ORA(AbsoluteYAddr); pc+=2; }*/
{
asm {
ORA(AbsoluteYAddr)
PC(#2)
}
}
void i1df() /*{ ORA(AbsoluteXAddr); pc+=2; }*/
{
asm {
ORA(AbsoluteXAddr)
PC(#2)
}
}
void i1ef() /*{ ASL(AbsoluteXAddr); pc+=2; }*/
{
asm {
ASL(AbsoluteXAddr)
PC(#2)
}
}
void i20f()
{
asm {
MOVE.W rPC,D1
ADDQ.W #1,D1
PushWord(D1)
WordAt(rPC,rPC)
}
}
void i21f() /*{ AND(IndirectXAddr); pc++; }*/
{
asm {
AND(IndirectXAddr)
PC(#1)
}
}
void i24f() /*{ BIT(ZeroPageAddr); pc++; }*/
{
asm {
BIT(ZeroPageAddr)
PC(#1)
}
}
void i25f() /*{ AND(ZeroPageAddr); pc++; }*/
{
asm {
AND(ZeroPageAddr)
PC(#1)
}
}
void i26f() /*{ ROL(ZeroPageAddr); pc++; }*/
{
asm {
ROL(ZeroPageAddr)
ADDQ.W #1,rPC
}
}
void i28f()
{
asm {
Pop(rFLAGS)
}
}
void i29f() /*{ a &= ImmediateByte(); FlagsNZ(a); pc++; }*/
{
asm {
ImmediateByte(D0)
AND.B D0,rA
FlagsNZ(rA)
ADDQ.W #1,rPC
}
}
void i2af() /*{
if (flags&CAR) {
if ((a&128)==0) flags &=~CAR;
a=(a<<1)|1; }
else {
if(a&128)flags|=CAR;
a=a<<1; }
FlagsNZ(a);
}*/
{
asm {
BTST #bCAR,rFLAGS
BEQ @x1
BTST #7,rA
BNE @x2
BCLR #bCAR,rFLAGS
@x2 LSL.B #1,rA
OR.B #1,rA
BRA @x3
@x1 BTST #7,rA
BEQ @x4
BSET #bCAR,rFLAGS
@x4 LSL.B #1,rA
@x3 FlagsNZ(rA)
}
}
void i2cf() /*{ BIT(AbsoluteAddr); pc+=2; }*/
{
asm {
BIT(AbsoluteAddr)
PC(#2)
}
}
void i2df() /*{ AND(AbsoluteAddr); pc+=2; }*/
{
asm {
AND(AbsoluteAddr)
PC(#2)
}
}
void i2ef() /*{ ROL(AbsoluteAddr); pc+=2; }*/
{
asm {
ROL(AbsoluteAddr)
PC(#2)
}
}
void i30f() /*{ BST(NEG); }*/
{
asm {
BST(#bNEG)
}
}
void i31f() /*{ AND(IndirectYAddr); pc++; }*/
{
asm {
AND(IndirectYAddr)
PC(#1)
}
}
void i35f() /*{ AND(ZeroPageXAddr); pc++; }*/
{
asm {
AND(ZeroPageXAddr)
PC(#1)
}
}
void i36f() /*{ ROL(ZeroPageXAddr); pc++; }*/
{
asm {
ROL(ZeroPageXAddr)
PC(#1)
}
}
void i38f() /*{ SET(CAR); }*/
{
asm {
SET(#bCAR)
}
}
void i39f() /*{ AND(AbsoluteYAddr); pc+=2; }*/
{
asm {
AND(AbsoluteYAddr)
PC(#2)
}
}
void i3df() /*{ AND(AbsoluteXAddr); pc+=2; }*/
{
asm {
AND(AbsoluteXAddr)
PC(#2)
}
}
void i3ef() /*{ ROL(AbsoluteXAddr); pc+=2; }*/
{
asm {
ROL(AbsoluteXAddr)
PC(#2)
}
}
void i40f() /*{ flags=Pop(); PopWord(pc); }*/
{
asm {
Pop(rFLAGS)
PopWord(rPC)
}
}
void i41f() /*{ EOR(IndirectXAddr); pc++; }*/
{
asm {
EOR(IndirectXAddr)
PC(#1)
}
}
void i45f() /*{ EOR(ZeroPageAddr); pc++; }*/
{
asm {
EOR(ZeroPageAddr)
PC(#1);
}
}
void i46f() /*{ LSR(ZeroPageAddr); pc++; }*/
{
asm {
LSR(ZeroPageAddr)
PC(#1)
}
}
void i48f()
{
asm {
Push(rA)
}
}
void i49f() /*{ a ^= ImmediateByte(); FlagsNZ(a); pc++; }*/
{
asm {
ImmediateByte(D1)
EOR.B D1,rA
FlagsNZ(rA)
PC(#1)
}
}
void i4af() /*{
flags &=~(CAR+NEG+ZER);
if (a&1) flags |=CAR;
if (a=a>>1); else flags |=ZER;
}*/
{
asm {
AND.B #0xFF-(CAR|NEG|ZER),rFLAGS
BTST #0,rA
BEQ @1
BSET #bCAR,rFLAGS
@1 LSR.B #1,rA
BNE @2
BSET #bZER,rFLAGS
@2
}
}
void i4cf() /*{ pc=WordAt(pc); }*/
{
asm {
WordAt(rPC,rPC)
}
}
void i4df() /*{ EOR(AbsoluteAddr); pc+=2; }*/
{
asm {
EOR(AbsoluteAddr)
PC(#2)
}
}
void i4ef() /*{ LSR(AbsoluteAddr); pc+=2; }*/
{
asm {
LSR(AbsoluteAddr)
PC(#2)
}
}
void i50f() /*{ BCL(OVF); }*/
{
asm {
BCL(#bOVF)
}
}
void i51f() /*{ EOR(IndirectYAddr); pc++; }*/
{
asm {
EOR(IndirectYAddr)
PC(#1)
}
}
void i55f() /*{ EOR(ZeroPageXAddr); pc++; }*/
{
asm {
EOR(ZeroPageXAddr)
PC(#1)
}
}
void i56f() /*{ LSR(ZeroPageXAddr); pc++; }*/
{
asm {
LSR(ZeroPageXAddr)
PC(#1)
}
}
void i58f() /*{ CLR(INT); }*/
{
asm {
CLR(#bINT)
}
}
void i59f() /*{ EOR(AbsoluteYAddr); pc+=2; }*/
{
asm {
EOR(AbsoluteYAddr)
PC(#2)
}
}
void i5df() /*{ EOR(AbsoluteXAddr); pc+=2; }*/
{
asm {
EOR(AbsoluteXAddr)
PC(#2)
}
}
void i5ef() /*{ LSR(AbsoluteXAddr); pc+=2; }*/
{
asm {
LSR(AbsoluteXAddr)
PC(#2)
}
}
void i60f() /*{ PopWord(pc); pc++; }*/
{
asm {
PopWord(rPC)
PC(#1)
}
}
void i61f() /*{ ADC(IndirectXAddr); pc++; }*/
{
asm {
ADC(IndirectXAddr)
PC(#1)
}
}
void i65f() /*{ ADC(ZeroPageAddr); pc++; }*/
{
asm {
ADC(ZeroPageAddr)
PC(#1)
}
}
void i66f() /*{ ROR(ZeroPageAddr); pc++; }*/
{
asm {
ROR(ZeroPageAddr)
PC(#1)
}
}
void i68f()
{
asm {
Pop(rA)
FlagsNZ(rA)
}
}
void i69f() /*{
register word data;
data=ImmediateByte();
if (flags&DEC) {
data = BCD2DEC(data)+BCD2DEC(a)+((flags&CAR)?1:0);
flags &= ~(CAR+OVF+NEG+ZER);
if (data>99) {
flags|=CAR+OVF;
data -=100; }
if (data==0) flags |= ZER;
else flags |= data&128;
DEC2BCD(data,a); }
else {
data += a+((flags&CAR)?1:0);
flags &= ~(CAR+OVF+NEG+ZER);
if (data>255) {
flags|=OVF+CAR;
data &=255; }
if (data==0) flags |= ZER;
else flags |= data&128;
a=data; }
pc++;
}*/
{
asm {
ImmediateByte(D1)
BTST #bDEC,rFLAGS
BNE @3
ANDI.W #0x00FF,rA
ADD.W D1,rA
BTST #bCAR,rFLAGS
BEQ @7
ADDQ.W #1,rA
@7 ANDI.B #0xFF-(CAR|OVF|NEG|ZER),rFLAGS
CMPI.W #0xFF,rA
BLS @8
OR.B #(OVF|CAR),rFLAGS
@8 FlagsNZ(rA)
BRA @6
@3 BCD2DEC(D1)
BCD2DEC(rA)
ADD.W D1,rA
BTST #bCAR,rFLAGS
BEQ @4
ADDQ.W #1,rA
@4 ANDI.B #0xFF-(CAR|OVF|NEG|ZER),rFLAGS
CMPI.W #99,rA
BLE @5
OR.B #(CAR|OVF),rFLAGS
SUBI.W #100,rA
@5 FlagsNZ(rA)
DEC2BCD(rA,rA)
@6 PC(#1)
}
}
void i6af() /*{
if (flags&CAR) {
if ((a&1)==0) flags &=~CAR;
a=(a>>1)|128; }
else {
if(a&1) flags|=CAR;
a=a>>1; }
FlagsNZ(a);
}*/
{
asm {
BTST #bCAR,rFLAGS
BEQ @3
BTST #0,rA
BNE @4
BCLR #bCAR,rFLAGS
@4 LSR.B #1,rA
OR.B #0x80,rA
BRA @5
@3 BTST #0,rA
BEQ @6
BSET #bCAR,rFLAGS
@6 LSR.B #1,rA
@5 FlagsNZ(rA)
}
}
void i6cf() /*{ register word ta; ta=WordAt(pc); pc=WordAt(ta); }*/
{
asm {
WordAt(rPC,D1)
WordAt(D1,rPC)
}
}
void i6df() /*{ ADC(AbsoluteAddr); pc+=2; }*/
{
asm {
ADC(AbsoluteAddr)
PC(#2)
}
}
void i6ef() /*{ ROR(AbsoluteAddr); pc+=2; }*/
{
asm {
ROR(AbsoluteAddr)
PC(#2)
}
}
void i70f() /*{ BST(OVF); }*/
{
asm {
BST(#bOVF)
}
}
void i71f() /*{ ADC(IndirectYAddr); pc++; }*/
{
asm {
ADC(IndirectYAddr)
PC(#1)
}
}
void i75f() /*{ ADC(ZeroPageXAddr); pc++; }*/
{
asm {
ADC(ZeroPageXAddr)
PC(#1)
}
}
void i76f() /*{ ROR(ZeroPageXAddr); pc++; }*/
{
asm {
ROR(ZeroPageXAddr)
PC(#1)
}
}
void i78f() /*{ SET(INT); }*/
{
asm {
SET(#bINT)
}
}
void i79f() /*{ ADC(AbsoluteYAddr); pc+=2; }*/
{
asm {
ADC(AbsoluteYAddr)
PC(#2)
}
}
void i7df() /*{ ADC(AbsoluteXAddr); pc+=2; }*/
{
asm {
ADC(AbsoluteXAddr)
PC(#2)
}
}
void i7ef() /*{ ROR(AbsoluteXAddr); pc+=2; }*/
{
asm {
ROR(AbsoluteXAddr)
PC(#2)
}
}
void i81f() /*{ STA(IndirectXAddr); pc++; }*/
{
asm {
STA(IndirectXAddr)
PC(#1)
}
}
void i84f() /*{ STY(ZeroPageAddr); pc++; }*/
{
asm {
STY(ZeroPageAddr)
PC(#1)
}
}
void i85f() /*{ STA(ZeroPageAddr); pc++; }*/
{
asm {
STA(ZeroPageAddr)
PC(#1)
}
}
void i86f() /*{ STX(ZeroPageAddr); pc++; }*/
{
asm {
STX(ZeroPageAddr)
PC(#1)
}
}
void i88f() /*{ y--; FlagsNZ(y); }*/
{
asm {
SUBQ.B #1,rY
FlagsNZ(rY)
}
}
void i8af() /*{ a=x; FlagsNZ(a); }*/
{
asm {
MOVE.B rX,rA
FlagsNZ(rA)
}
}
void i8cf() /*{ STY(AbsoluteAddr); pc+=2; }*/
{
asm {
STY(AbsoluteAddr)
PC(#2)
}
}
void i8df() /*{ STA(AbsoluteAddr); pc+=2; }*/
{
asm {
STA(AbsoluteAddr)
PC(#2)
}
}
void i8ef() /*{ STX(AbsoluteAddr); pc+=2; }*/
{
asm {
STX(AbsoluteAddr)
PC(#2)
}
}
void i90f() /*{ BCL(CAR); }*/
{
asm {
BCL(#bCAR)
}
}
void i91f() /*{ STA(IndirectYAddr); pc++; }*/
{
asm {
STA(IndirectYAddr)
PC(#1)
}
}
void i94f() /*{ STY(ZeroPageXAddr); pc++; }*/
{
asm {
STY(ZeroPageXAddr)
PC(#1)
}
}
void i95f() /*{ STA(ZeroPageXAddr); pc++; }*/
{
asm {
STA(ZeroPageXAddr)
PC(#1)
}
}
void i96f() /*{ STX(ZeroPageYAddr); pc++; }*/
{
asm {
STX(ZeroPageYAddr)
PC(#1)
}
}
void i98f() /*{ a=y; FlagsNZ(a); }*/
{
asm {
MOVE.B rY,rA
FlagsNZ(rA)
}
}
void i99f() /*{ STA(AbsoluteYAddr); pc+=2; }*/
{
asm {
STA(AbsoluteYAddr)
PC(#2)
}
}
void i9af() /*{ sp=x; }*/
{
asm {
MOVE.B rX,rSP
}
}
void i9df() /*{ STA(AbsoluteXAddr); pc+=2; }*/
{
asm {
STA(AbsoluteXAddr)
PC(#2)
}
}
void ia0f() /*{ y=ImmediateByte(); FlagsNZ(y); pc++; }*/
{
asm {
ImmediateByte(rY)
FlagsNZ(rY)
PC(#1)
}
}
void ia1f() /*{ LDA(IndirectXAddr); pc++; }*/
{
asm {
LDA(IndirectXAddr)
PC(#1)
}
}
void ia2f() /*{ x=ImmediateByte(); FlagsNZ(x); pc++; }*/
{
asm {
ImmediateByte(rX)
FlagsNZ(rX)
PC(#1)
}
}
void ia4f() /*{ LDY(ZeroPageAddr); pc++; }*/
{
asm {
LDY(ZeroPageAddr)
PC(#1)
}
}
void ia5f() /*{ LDA(ZeroPageAddr); pc++; }*/
{
asm {
LDA(ZeroPageAddr)
PC(#1)
}
}
void ia6f() /*{ LDX(ZeroPageAddr); pc++; }*/
{
asm {
LDX(ZeroPageAddr)
PC(#1)
}
}
void ia8f() /*{ y=a; FlagsNZ(y); }*/
{
asm {
MOVE.B rA,rY
FlagsNZ(rY)
}
}
void ia9f()
{
asm {
ImmediateByte(rA)
FlagsNZ(rA)
PC(#1)
}
}
void iaaf() /*{ x=a; FlagsNZ(x); }*/
{
asm {
MOVE.B rA,rX
FlagsNZ(rX)
}
}
void iacf() /*{ LDY(AbsoluteAddr); pc+=2; }*/
{
asm {
LDY(AbsoluteAddr)
PC(#2)
}
}
void iadf() /*{ LDA(AbsoluteAddr); pc+=2; }*/
{
asm {
LDA(AbsoluteAddr)
PC(#2)
}
}
void iaef() /*{ LDX(AbsoluteAddr); pc+=2; }*/
{
asm {
LDX(AbsoluteAddr)
PC(#2)
}
}
void ib0f() /*{ BST(CAR); }*/
{
asm {
BST(#bCAR)
}
}
void ib1f() /*{ LDA(IndirectYAddr); pc++; }*/
{
asm {
LDA(IndirectYAddr)
PC(#1)
}
}
void ib4f() /*{ LDY(ZeroPageXAddr); pc++; }*/
{
asm {
LDY(ZeroPageXAddr)
PC(#1)
}
}
void ib5f() /*{ LDA(ZeroPageXAddr); pc++; }*/
{
asm {
LDA(ZeroPageXAddr)
PC(#1)
}
}
void ib6f() /*{ LDX(ZeroPageYAddr); pc++; }*/
{
asm {
LDX(ZeroPageYAddr)
PC(#1)
}
}
void ib8f() /*{ CLR(OVF); }*/
{
asm {
CLR(#bOVF)
}
}
void ib9f() /*{ LDA(AbsoluteYAddr); pc+=2; }*/
{
asm {
LDA(AbsoluteYAddr)
PC(#2)
}
}
void ibaf() /*{ x=sp; }*/
{
asm {
MOVE.B rSP,rX
}
}
void ibcf() /*{ LDY(AbsoluteXAddr); pc+=2; }*/
{
asm {
LDY(AbsoluteXAddr)
PC(#2)
}
}
void ibdf() /*{ LDA(AbsoluteXAddr); pc+=2; }*/
{
asm {
LDA(AbsoluteXAddr)
PC(#2)
}
}
void ibef() /*{ LDX(AbsoluteYAddr); pc+=2; }*/
{
asm {
LDX(AbsoluteYAddr)
PC(#2)
}
}
void ic0f() /*{
register byte tbyte;
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (y==tbyte) flags |=CAR+ZER;
else if (y>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
}*/
{
asm {
CPI(rY)
PC(#1)
}
}
void ic1f() /*{ CMP(IndirectXAddr); pc++; }*/
{
asm {
CMP(IndirectXAddr)
PC(#1)
}
}
void ic4f() /*{ CPY(ZeroPageAddr); pc++; }*/
{
asm {
CPY(ZeroPageAddr)
PC(#1)
}
}
void ic5f() /*{ CMP(ZeroPageAddr); pc++; }*/
{
asm {
CMP(ZeroPageAddr)
PC(#1)
}
}
void ic6f() /*{ DECR(ZeroPageAddr); pc++; }*/
{
asm {
DECR(ZeroPageAddr)
PC(#1)
}
}
void ic8f() /*{ y++; FlagsNZ(y); }*/
{
asm {
ADDQ.B #1,rY
FlagsNZ(rY)
}
}
void ic9f() /*{
register byte tbyte;
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (a==tbyte) flags |=CAR+ZER;
else if (a>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
}*/
{
asm {
CPI(rA)
PC(#1)
}
}
void icaf() /*{ x--; FlagsNZ(x); }*/
{
asm {
SUBQ.B #1,rX
FlagsNZ(rX)
}
}
void iccf() /*{ CPY(AbsoluteAddr); pc+=2; }*/
{
asm {
CPY(AbsoluteAddr)
PC(#2)
}
}
void icdf() /*{ CMP(AbsoluteAddr); pc+=2; }*/
{
asm {
CMP(AbsoluteAddr)
PC(#2)
}
}
void icef() /*{ DECR(AbsoluteAddr); pc+=2; }*/
{
asm {
DECR(AbsoluteAddr)
PC(#2)
}
}
void id0f() /*{ BCL(ZER); }*/
{
asm {
BCL(#bZER)
}
}
void id1f() /*{ CMP(IndirectYAddr); pc++; }*/
{
asm {
CMP(IndirectYAddr)
PC(#1)
}
}
void id5f() /*{ CMP(ZeroPageXAddr); pc++; }*/
{
asm {
CMP(ZeroPageXAddr)
PC(#1)
}
}
void id6f() /*{ DECR(ZeroPageXAddr); pc++; }*/
{
asm {
DECR(ZeroPageXAddr)
PC(#1)
}
}
void id8f() /*{ CLR(DEC); }*/
{
asm {
CLR(#bDEC)
}
}
void id9f() /*{ CMP(AbsoluteYAddr); pc+=2; }*/
{
asm {
CMP(AbsoluteYAddr)
PC(#2)
}
}
void iddf() /*{ CMP(AbsoluteXAddr); pc+=2; }*/
{
asm {
CMP(AbsoluteXAddr)
PC(#2)
}
}
void idef() /*{ DECR(AbsoluteXAddr); pc+=2; }*/
{
asm {
DECR(AbsoluteXAddr)
PC(#2)
}
}
void ie0f() /*{
register byte tbyte;
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (x==tbyte) flags |=CAR+ZER;
else if (x>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
}*/
{
asm {
CPI(rX)
PC(#1)
}
}
void ie1f() /*{ SBC(IndirectXAddr); pc++; }*/
{
asm {
SBC(IndirectXAddr)
PC(#1)
}
}
void ie4f() /*{ CPX(ZeroPageAddr); pc++; }*/
{
asm {
CPX(ZeroPageAddr)
PC(#1)
}
}
void ie5f() /*{ SBC(ZeroPageAddr); pc++; }*/
{
asm {
SBC(ZeroPageAddr)
PC(#1)
}
}
void ie6f() /*{ INCR(ZeroPageAddr); pc++; }*/
{
asm {
INCR(ZeroPageAddr)
PC(#1)
}
}
void ie8f() /*{ x++; FlagsNZ(x); }*/
{
asm {
ADDQ.B #1,rX
FlagsNZ(rX)
}
}
void ie9f() /*{
register int data;
data=ImmediateByte();
if (flags&DEC) {
data = BCD2DEC(a)-BCD2DEC(data)-((flags&CAR)?0:1);
flags &= ~(CAR+ZER+NEG+OVF);
if (data==0) flags |=ZER+CAR;
else if (data>0) flags |=CAR;
else {
flags|=NEG;
data +=100; }
DEC2BCD(data,a); }
else {
data = a-data-((flags&CAR)?0:1);
flags &=~(CAR+ZER+OVF+NEG);
if (data==0) flags |= ZER+CAR;
else if (data>0) flags |= CAR;
else flags|=OVF;
data &= 255;
flags |= data&128;
a=data; }
pc++;
}*/
{
asm {
ImmediateByte(D1)
BTST #bDEC,rFLAGS
BNE @3
ANDI.W #0x00FF,rA
SUB.W D1,rA
BTST #bCAR,rFLAGS
BNE @7
SUB.W #1,rA
@7 ANDI.B #0xFF-(CAR|OVF|NEG|ZER),rFLAGS
TST.W rA
BNE @8
OR.B #(ZER|CAR),rFLAGS
BRA @9
@8 BMI @10
BSET #bCAR,rFLAGS
BRA @9
@10 BSET #bOVF,rFLAGS
@9 NegSet(rA)
BRA @6
@3 BCD2DEC(D1)
BCD2DEC(rA)
SUB.W D1,rA
BTST #bCAR,rFLAGS
BNE @4
SUB.W #1,rA
@4 ANDI.B #0xFF-(CAR|OVF|NEG|ZER),rFLAGS
TST.W rA
BNE @5
OR.B #(ZER|CAR),rFLAGS
BRA @11
@5 BMI @12
BSET #bCAR,rFLAGS
BRA @11
@12 BSET #bNEG,rFLAGS
ADDI.W #100,rA
@11 DEC2BCD(rA,rA)
@6 PC(#1)
}
}
void ieaf() {}
void iecf() /*{ CPX(AbsoluteAddr); pc+=2; }*/
{
asm {
CPX(AbsoluteAddr)
PC(#2)
}
}
void iedf() /*{ SBC(AbsoluteAddr); pc+=2; }*/
{
asm {
SBC(AbsoluteAddr)
PC(#2)
}
}
void ieef() /*{ INCR(AbsoluteAddr); pc+=2; }*/
{
asm {
INCR(AbsoluteAddr)
PC(#2)
}
}
void if0f() /*{ BST(ZER); }*/
{
asm {
BST(#bZER)
}
}
void if1f() /*{ SBC(IndirectYAddr); pc++; }*/
{
asm {
SBC(IndirectYAddr)
PC(#1)
}
}
void if5f() /*{ SBC(ZeroPageXAddr); pc++; }*/
{
asm {
SBC(ZeroPageXAddr)
PC(#1)
}
}
void if6f() /*{ INCR(ZeroPageXAddr); pc++; }*/
{
asm {
INCR(ZeroPageXAddr)
PC(#1)
}
}
void if8f() /*{ SET(DEC); }*/
{
asm {
SET(#bDEC)
}
}
void if9f() /*{ SBC(AbsoluteYAddr); pc+=2; }*/
{
asm {
SBC(AbsoluteYAddr)
PC(#2)
}
}
void ifdf() /*{ SBC(AbsoluteXAddr); pc+=2; }*/
{
asm {
SBC(AbsoluteXAddr)
PC(#2)
}
}
void ifef() /*{ INCR(AbsoluteXAddr); pc+=2; }*/
{
asm {
INCR(AbsoluteXAddr)
PC(#2)
}
}
void ifff()
{
word tpc, tsp;
extern byte *RAM, **memory;
asm {
MOVE.W rPC,tpc
MOVE.W rSP,tsp
MOVE.B rA,a
MOVE.B rX,x
MOVE.B rY,y
MOVE.B rFLAGS,flags
}
pc = tpc;
sp = tsp;
TrapExecute();
tpc = pc;
tsp = sp;
asm {
MOVE.W tpc,rPC
MOVE.W tsp,rSP
MOVE.B a,rA
MOVE.B x,rX
MOVE.B y,rY
MOVE.B flags,rFLAGS
MOVEA.L RAM,rRAM
MOVE.L rRAM,rSTACK
ADDA.L #256,rSTACK
MOVEA.L memory,rMEMORY
}
}
void inif()
{
#ifdef MACSBUG
DebugStr("\pNonImplemented!");
#endif
asm {
PC(#2)
}
}
void InstructionInitializef()
{ }
void (* instructf[256]) () = {
i00f, i01f, inif, inif, inif, i05f, i06f, inif,
i08f, i09f, i0af, inif, inif, i0df, i0ef, inif,
i10f, i11f, inif, inif, inif, i15f, i16f, inif,
i18f, i19f, inif, inif, inif, i1df, i1ef, inif,
i20f, i21f, inif, inif, i24f, i25f, i26f, inif,
i28f, i29f, i2af, inif, i2cf, i2df, i2ef, inif,
i30f, i31f, inif, inif, inif, i35f, i36f, inif,
i38f, i39f, inif, inif, inif, i3df, i3ef, inif,
i40f, i41f, inif, inif, inif, i45f, i46f, inif,
i48f, i49f, i4af, inif, i4cf, i4df, i4ef, inif,
i50f, i51f, inif, inif, inif, i55f, i56f, inif,
i58f, i59f, inif, inif, inif, i5df, i5ef, inif,
i60f, i61f, inif, inif, inif, i65f, i66f, inif,
i68f, i69f, i6af, inif, i6cf, i6df, i6ef, inif,
i70f, i71f, inif, inif, inif, i75f, i76f, inif,
i78f, i79f, inif, inif, inif, i7df, i7ef, inif,
inif, i81f, inif, inif, i84f, i85f, i86f, inif,
i88f, inif, i8af, inif, i8cf, i8df, i8ef, inif,
i90f, i91f, inif, inif, i94f, i95f, i96f, inif,
i98f, i99f, i9af, inif, inif, i9df, inif, inif,
ia0f, ia1f, ia2f, inif, ia4f, ia5f, ia6f, inif,
ia8f, ia9f, iaaf, inif, iacf, iadf, iaef, inif,
ib0f, ib1f, inif, inif, ib4f, ib5f, ib6f, inif,
ib8f, ib9f, ibaf, inif, ibcf, ibdf, ibef, inif,
ic0f, ic1f, inif, inif, ic4f, ic5f, ic6f, inif,
ic8f, ic9f, icaf, inif, iccf, icdf, icef, inif,
id0f, id1f, inif, inif, inif, id5f, id6f, inif,
id8f, id9f, inif, inif, inif, iddf, idef, inif,
ie0f, ie1f, inif, inif, ie4f, ie5f, ie6f, inif,
ie8f, ie9f, ieaf, inif, iecf, iedf, ieef, inif,
if0f, if1f, inif, inif, inif, if5f, if6f, inif,
if8f, if9f, inif, inif, inif, ifdf, ifef, ifff};
byte cycletimef[256]={
/*00*/ 7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0,
/*10*/ 3, 5, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
/*20*/ 6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0,
/*30*/ 3, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
/*40*/ 6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0,
/*50*/ 3, 6, 0, 0, 0, 3, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
/*60*/ 6, 6, 0, 0, 0, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0,
/*70*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
/*80*/ 0, 6, 0, 0, 6, 3, 3, 0, 2, 0, 2, 0, 4, 4, 4, 0,
/*90*/ 2, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 0, 5, 0, 0,
/*A0*/ 2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0,
/*B0*/ 3, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 5, 5, 5, 0,
/*C0*/ 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
/*D0*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
/*E0*/ 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
/*F0*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 1 };
#endif